package com.sea.physical.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.codecrane.core.util.CountryMoneyTypeEnum;
import com.codecrane.core.util.DateUtils;
import com.sea.data.entity.OrderDetail;
import com.sea.data.service.OrderDetailService;
import com.sea.physical.entity.*;
import com.sea.physical.mapper.CreateDistributePlanMapper;
import com.sea.physical.mapper.CreateDistributeSkuMapper;
import com.sea.physical.service.*;
import com.sea.supply.entity.ProduceDetail;
import com.sea.supply.entity.WareDistribute;
import com.sea.supply.entity.WareProduce;
import com.sea.supply.service.ProduceDetailService;
import com.sea.supply.service.SupplierService;
import com.sea.supply.service.WareDistributeService;
import com.sea.supply.service.WareProduceService;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.*;

@Service
public class CreateDistributePlanServiceImpl implements CreateDistributePlanService {
    @Autowired
    private CreateDistributePlanMapper createDistributePlanMapper;
    @Autowired
    private CreateDistributeSkuService createDistributeSkuService;
    @Autowired
    private CreateDespatchPlanService createDespatchPlanService;
    @Autowired
    private CreateDespatchSkuService createDespatchSkuService;
    @Autowired
    private CreatePlanService createPlanService;
    @Autowired
    private CreateSkuService createSkuService;
    @Autowired
    private RecordService recordService;
    @Autowired
    private ProduceDetailService produceDetailService;
    @Autowired
    private CreateDistributePlanService createDistributePlanService;
    @Autowired
    private SupplierService supplierService;

    @Autowired
    private WareDistributeService wareDistributeService;
    @Autowired
    private CreatePackingSkuService createPackingSkuService;
    @Autowired
    private OrderDetailService orderDetailService;
    @Autowired
    private OAuth2ClientService oAuth2ClientService;
    @Autowired
    private CreatePlanSupplierFileService createPlanSupplierFileService;

    @Override
    public CreateDistributePlan findByCreateId(Integer createId) {
        return createDistributePlanMapper.findByCreateId(createId);
    }

    @Override
    public int save(CreateDistributePlan createDistributePlan) {
        return createDistributePlanMapper.insert(createDistributePlan);
    }

    @Override
    public List<CreateDistributePlan> findByCnd(CreateDistributePlan createDistributePlan) {
        return createDistributePlanMapper.findByCnd(createDistributePlan);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void distribute(Integer id) throws Exception {
        List<CreateSku> list = createSkuService.findByCreateId(id);
        for (CreateSku createSku : list) {
            CreateDistributeSku createDistributeSku = new CreateDistributeSku();
            createDistributeSku.setCreateId(id);
            createDistributeSku.setCreateSkuId(createSku.getId());
            createDistributeSku.setCreateNumber(createSku.getCreateNumber());
            createDistributeSku.setCreateBoxNumber(createSku.getCreateBoxNumber());
            createDistributeSku.setCreateNumberTotal(createSku.getCreateNumberTotal());
            createDistributeSku.setCreateWeightTotal(createSku.getCreateWeightTotal());
            createDistributeSku.setCreateKgTotal(createSku.getCreateKgTotal());
            createDistributeSku.setCreateVolumeTotal(createSku.getCreateVolumeTotal());
            createDistributeSkuService.save(createDistributeSku);
        }
        createDistributePlanMapper.updateTotal(id);
        //更新分配状态
        createPlanService.updateStatus(2, id);
        //新增记录
        recordService.save(id, 2, "", DateUtils.dateToString(new Date()));
        //更新占有的柜号
        createDistributeSkuService.updateCreatePlanNo();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancel(Integer createId) throws Exception {

        List<CreateDistributeSku> list = createDistributeSkuService.findByCreateId(createId);
        for (CreateDistributeSku distributeSku : list) {
            //获取数量
            Integer createNumber = distributeSku.getCreateNumber();
            //采购ID
            Integer createProduceId = distributeSku.getCreateProduceId();

            String createSupplierName = distributeSku.getCreateSupplierName();
            String supplierWare = supplierService.findBySupplierName(createSupplierName).getSupplierWare();
            if (supplierWare.equals("否")) {
                //根据ID查找指定
                ProduceDetail produceDetail = produceDetailService.findById(createProduceId);
                //计算需要释放的占有量
                if (produceDetail.getProduceUse() - createNumber < 0) {
                    throw new RuntimeException("释放占有量异常,请联系管理员！");
                }
                //释放占有量
                produceDetailService.updateUseNumber(produceDetail.getProduceUse() - createNumber, createProduceId);
            } else {
                WareDistribute wareDistribute = wareDistributeService.findById(createProduceId);
                wareDistributeService.updateUseNumber(wareDistribute.getProduceUse() - createNumber, createProduceId);
            }
        }
        //删除分配明细
        createDistributeSkuService.deleteByCreateId(createId);
        //删除发运信息
        createDespatchPlanService.delete(createId);
        //删除发运明细
        createDespatchSkuService.delete(createId);
        //更新表头
        createDistributePlanMapper.updateTotal(createId);
        //更新分配状态
        createPlanService.updateStatus(1, createId);
        //新增记录
        recordService.save(createId, 21, "取消分配", DateUtils.dateToString(new Date()));
        //删除泛微数据
        CreatePlan createPlan = createPlanService.findById(createId);
        createPlanSupplierFileService.deleteByCreatePlanNo(createPlan.getCreatePlanNo());
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void send(Integer createId) throws Exception {
        //查询分配表头信息
        CreateDistributePlan createDistributePlan = createDistributePlanService.findByCreateId(createId);
        //查询计划信息
        CreatePlan createPlan = createPlanService.findById(createId);
        if (!createPlan.getCreatePlanTotal().equals(createDistributePlan.getCreatePlanTotal())) {
            throw new RuntimeException("计划数量和分配数量不一致！请检查！");
        }
        CreateDespatchPlan createDespatchPlan = createDespatchPlanService.findByCreateId(createId);
        if (null != createDespatchPlan) {
            throw new RuntimeException("发运计划已存在！");
        }
        List<CreateDistributeSku> list = createDistributeSkuService.findByCreateId(createId);
        if (null == list || list.size() == 0) {
            throw new RuntimeException("请先分配PO信息！");
        }
        createDespatchPlanService.save(createId);
        //更新表头合计
        createDespatchPlanService.updateTotal(createId);

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateTotal(Integer createId) {

        Integer boxNumber = createPackingSkuService.findBoxNumberByCreateId(createId);
        if (null == boxNumber) {
            return createDistributePlanMapper.updateTotal(createId);
        } else {
            createDistributePlanMapper.updateTotal(createId);
            return createDistributePlanMapper.updateBoxNumberByCreateId(boxNumber, createId);
        }

    }

    @Override
    public Integer updateBoxNumberByCreateId(Integer boxNumber, Integer id) {
        return createDistributePlanMapper.updateBoxNumberByCreateId(boxNumber, id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void cancelAutoDistribute(Integer createId) {
        List<CreateDistributeSku> list = createDistributeSkuService.findByCreateId(createId);
        for (CreateDistributeSku distributeSku : list) {
            //获取数量
            Integer createNumber = distributeSku.getCreateNumber();
            //采购ID
            Integer createProduceId = distributeSku.getCreateProduceId();

            String createSupplierName = distributeSku.getCreateSupplierName();
            String supplierWare = supplierService.findBySupplierName(createSupplierName).getSupplierWare();
            ProduceDetail produceDetail = produceDetailService.findById(createProduceId);
            if (supplierWare.equals("否")) {
                //根据ID查找指定

                //计算需要释放的占有量
                if (produceDetail.getProduceReadyUse() - createNumber < 0) {
                    throw new RuntimeException("释放占有量异常,请联系管理员！");
                }
                //释放占有量
                produceDetailService.updateReadyUseNumber(produceDetail.getProduceReadyUse() - createNumber, createProduceId);
            } else {
                WareDistribute wareDistribute = wareDistributeService.findById(createProduceId);
                if (wareDistribute.getProduceReadyUse() - createNumber < 0) {
                    throw new RuntimeException("释放占有量异常,请联系管理员！");
                }
                //释放占有量
                wareDistributeService.updateReadyUseNumber(wareDistribute.getProduceReadyUse() - createNumber, createProduceId);
            }
        }
        //删除分配明细
        createDistributeSkuService.deleteByCreateId(createId);
        //删除发运信息
        createDespatchPlanService.delete(createId);
        //删除发运明细
        createDespatchSkuService.delete(createId);
        //更新表头
        createDistributePlanMapper.updateTotal(createId);
        //更新分配状态
        createPlanService.updateStatus(1, createId);
        //新增记录
        recordService.save(createId, 23, "取消自动分配", DateUtils.dateToString(new Date()));

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void sureAutoDistribute(Integer createId) {
        List<CreateDistributeSku> list = createDistributeSkuService.findByCreateId(createId);
        for (CreateDistributeSku distributeSku : list) {
            //获取数量
            Integer createNumber = distributeSku.getCreateNumber();
            //采购ID
            Integer createProduceId = distributeSku.getCreateProduceId();

            String createSupplierName = distributeSku.getCreateSupplierName();
            String supplierWare = supplierService.findBySupplierName(createSupplierName).getSupplierWare();
            if (supplierWare.equals("否")) {
                //根据ID查找指定
                ProduceDetail produceDetail = produceDetailService.findById(createProduceId);
                //计算需要释放的占有量
                if (produceDetail.getProduceReadyUse() - createNumber < 0) {
                    throw new RuntimeException("释放占有量异常,请联系管理员！");
                }
                //释放预占有量
                produceDetailService.updateReadyUseNumber(produceDetail.getProduceReadyUse() - createNumber, createProduceId);
                //更新实际占有量
                if ((createNumber) > (produceDetail.getProduceSurplus() - produceDetail.getProduceShort() - produceDetail.getProduceUse())) {
                    OrderDetail orderDetail = orderDetailService.findById(produceDetail.getDetailId());
                    throw new RuntimeException("占有量异常,超出可分配数量,请重新自动分配！<br />SKU: " + orderDetail.getOrderSku());
                } else {
                    produceDetailService.updateUseNumber(produceDetail.getProduceUse() + createNumber, createProduceId);
                }
            } else {
                WareDistribute wareDistribute = wareDistributeService.findById(createProduceId);
                if (wareDistribute.getProduceReadyUse() - createNumber < 0) {
                    throw new RuntimeException("释放占有量异常,请联系管理员！");
                }
                //释放预占有量
                wareDistributeService.updateReadyUseNumber(wareDistribute.getProduceReadyUse() - createNumber, createProduceId);
                if ((createNumber) > (wareDistribute.getReceiveNumber() - wareDistribute.getProduceUse())) {
                    throw new RuntimeException("占有量异常,超出可分配数量,请重新自动分配！<br />SKU: " + wareDistribute.getReceiveSku());
                } else {
                    wareDistributeService.updateUseNumber(wareDistribute.getProduceUse() + createNumber, createProduceId);
                }
            }
        }
        //更新分配状态
        createPlanService.updateStatus(2, createId);
        //新增记录
        recordService.save(createId, 2, "已分配", DateUtils.dateToString(new Date()));
    }

    @Override
    public void uploadFwFile(Integer createId, String accessToken) throws Exception {

        CreatePlan createPlan = createPlanService.findById(createId);
        CreatePlanSupplierFile createPlanSupplierFile = new CreatePlanSupplierFile();
        createPlanSupplierFile.setCreatePlanNo(createPlan.getCreatePlanNo());



        List<CreateDistributeSku> supplierList = createDistributeSkuService.findDistributeSkuBySupplierName(createId);
        if(null==supplierList || supplierList.size()==0){
            throw new RuntimeException("暂未查询到供应商分配信息！");
        }else{
            for(CreateDistributeSku distributeSku:supplierList){
                List<CreateDistributeSku> exportList=new ArrayList<>();
                createPlanSupplierFile.setSupplierName(distributeSku.getCreateSupplierName());
                List<CreateDistributeSku> skuList=createDistributeSkuService.findByCreateIdSupplierName(createId,distributeSku.getCreateSupplierName());
                for(CreateDistributeSku createDistributeSku:skuList){

                    CreateDistributeSku exportDistributeSku=new CreateDistributeSku();
                    String createSupplierName = createDistributeSku.getCreateSupplierName();
                    String supplierWare = supplierService.findBySupplierName(createSupplierName).getSupplierWare();
                    if(supplierWare.equals("是")){
                        WareDistribute wareDistribute = wareDistributeService.findById(createDistributeSku.getCreateProduceId());
                        exportDistributeSku.setErpProducePo(wareDistribute.getProduceNo());
                        exportDistributeSku.setCreateSupplierName(createDistributeSku.getCreateSupplierName());
                        exportDistributeSku.setCreateChannelName(wareDistribute.getReceiveChannelName());
                        exportDistributeSku.setCreateSku(wareDistribute.getReceiveSku());
                        exportDistributeSku.setCreateNumber(createDistributeSku.getCreateNumber());
                    }else{
                        CreateDistributeSku dSku = createDistributeSkuService.findDetailById(createDistributeSku.getId());
                        exportDistributeSku.setErpProducePo(dSku.getErpProducePo());
                        exportDistributeSku.setCreateSupplierName(createDistributeSku.getCreateSupplierName());
                        exportDistributeSku.setCreateChannelName(dSku.getCreateChannelName());
                        exportDistributeSku.setCreateSku(dSku.getCreateSku());
                        exportDistributeSku.setCreateNumber(createDistributeSku.getCreateNumber());
                        exportDistributeSku.setOrderDate(dSku.getOrderDate());
                    }
                    exportList.add(exportDistributeSku);
                }


                String[] title = {"PO号", "供应商", "渠道", "SKU", "分配数量", "预计交期"};
                String fileName = createPlan.getCreatePlanNo()+String.valueOf(System.currentTimeMillis()) +".xls";
                String sheetName = "出运明细表";
                String[][] content = new String[exportList.size()][6];
                for (int i = 0; i < exportList.size(); i++) {
                    content[i] = new String[title.length];
                    CreateDistributeSku obj = exportList.get(i);
                    content[i][0] = obj.getErpProducePo();
                    content[i][1] = obj.getCreateSupplierName();
                    content[i][2] = obj.getCreateChannelName();
                    content[i][3] = obj.getCreateSku();
                    content[i][4] = obj.getCreateNumber() + "";
                    content[i][5] = obj.getOrderDate();
                }
                // Create Excel workbook
                Workbook workbook = new HSSFWorkbook();
                Sheet sheet = workbook.createSheet(sheetName);
                // Create header row
                Row headerRow = sheet.createRow(0);
                for (int i = 0; i < title.length; i++) {
                    Cell cell = headerRow.createCell(i);
                    cell.setCellValue(title[i]);

                    // Style for header
                    CellStyle headerStyle = workbook.createCellStyle();
                    Font headerFont = workbook.createFont();
                    headerFont.setBold(true);
                    headerStyle.setFont(headerFont);
                    cell.setCellStyle(headerStyle);
                }

                // Fill data
                for (int i = 0; i < content.length; i++) {
                    Row row = sheet.createRow(i + 1);
                    for (int j = 0; j < content[i].length; j++) {
                        row.createCell(j).setCellValue(content[i][j]);
                    }
                }

                // Auto-size columns
                for (int i = 0; i < title.length; i++) {
                    sheet.autoSizeColumn(i);
                }

                // Convert to Base64
                ByteArrayOutputStream bos = new ByteArrayOutputStream();
                workbook.write(bos);
                byte[] bytes = bos.toByteArray();
                String base64String = Base64.encodeBase64String(bytes);

                // Now you have the Base64 encoded Excel file
//                System.out.println("Base64 Excel data: " + base64String);
//                System.out.println("Base64 Excel size: " + bytes.length);
//                System.out.println("Base64 Excel time: " + System.currentTimeMillis());

                String fileId = oAuth2ClientService.uploadBase64File(accessToken, "1100795470840750109", base64String, fileName, (long) bytes.length, System.currentTimeMillis());
                if(null != fileId && StringUtils.isNotBlank(fileId)){
                    createPlanSupplierFile.setFileId(fileId);
                    createPlanSupplierFileService.save(createPlanSupplierFile);
                }else{
                    throw new RuntimeException("文件上传异常,请联系管理员");
                }
            }
        }
    }

    @Override
    public void sendFwPostData(Integer createId, String accessToken) throws Exception {

        CreatePlan createPlan = createPlanService.findById(createId);

        List<CreatePlanSupplierFile> list = createPlanSupplierFileService.findByCreatePlanNo(createPlan.getCreatePlanNo());

        if(null==list || list.size()==0 ){
            throw new RuntimeException("暂未获取到数据！");
        }else {
            for(CreatePlanSupplierFile supplierFile:list){
                JSONObject root = new JSONObject();
                root.put("access_token", accessToken);
                root.put("userid", "1100795470840750109");
                root.put("workflowId", "1100425180250833131");

                root.put("isnextflow",1);
                // formData 对象
                JSONObject formData = new JSONObject();
                JSONArray dataDetails = new JSONArray();

                // 构造 dataDetails 中的每一项
                JSONObject item1 = new JSONObject();
                item1.put("content", supplierFile.getSupplierName());
                item1.put("dataKey", "gys");

                JSONObject item2 = new JSONObject();
                item2.put("content", createPlan.getCreatePlanNo());
                item2.put("dataKey", "jh");

                JSONObject item3 = new JSONObject();
                item3.put("content", createPlan.getCreatePlanPlaceDate());
                item3.put("dataKey", "zjrq");

                // 带 dataOptions 的项
                JSONObject item4 = new JSONObject();
                item4.put("content", "附件上传");
                item4.put("dataKey", "cyjhmx");

                // dataOptions 是数组
                JSONArray dataOptions = new JSONArray();
                JSONObject option = new JSONObject();
                option.put("content", "图片");
                option.put("optionId", supplierFile.getFileId());
                option.put("type", "file");

                dataOptions.add(option);
                item4.put("dataOptions", dataOptions);

                // 添加所有 items 到 dataDetails
                dataDetails.add(item1);
                dataDetails.add(item2);
                dataDetails.add(item3);
                dataDetails.add(item4);

                formData.put("dataDetails", dataDetails);
                root.put("formData", formData);

                // 输出完整 JSON
                System.out.println("构造后的 JSON：");
                System.out.println(root.toJSONString());

                String s = oAuth2ClientService.getWorkFlow(root.toJSONString());
                System.out.println(s);
                JSONObject jsonObject = JSONObject.parseObject(s);
                JSONObject message = jsonObject.getJSONObject("message");
                if(StringUtils.isNotBlank(message.getString("requestId"))) {
                    createPlanSupplierFileService.updateRequestId(message.getString("requestId"),createPlan.getCreatePlanNo(),supplierFile.getSupplierName());
                }
                System.out.println(s);

            }
        }
    }
}
